package cn.dglydrpy.fundmanagement.service.impl;

import cn.dglydrpy.fundmanagement.dao.entiey.Fund;
import cn.dglydrpy.fundmanagement.dao.entiey.Portfolio;
import cn.dglydrpy.fundmanagement.dao.entiey.PortfolioFund;
import cn.dglydrpy.fundmanagement.dao.entiey.Transaction;
import cn.dglydrpy.fundmanagement.dao.mapper.FundMapper;
import cn.dglydrpy.fundmanagement.dao.mapper.PortfolioFundMapper;
import cn.dglydrpy.fundmanagement.dao.mapper.PortfolioMapper;
import cn.dglydrpy.fundmanagement.dao.mapper.TransactionMapper;
import cn.dglydrpy.fundmanagement.service.IPortfolioService;
import cn.dglydrpy.fundmanagement.service.dto.PortfolioDto;
import cn.dglydrpy.fundmanagement.service.dto.PortfolioFundDto;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class PortfolioService implements IPortfolioService {

    @Autowired
    private PortfolioMapper portfolioMapper;

    @Autowired
    private PortfolioFundMapper portfolioFundMapper;

    @Autowired
    private FundMapper fundMapper;
    
    @Autowired
    private TransactionMapper transactionMapper;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
    /**
     * 从交易记录中计算基金的持仓信息
     * @param fundDto 基金DTO
     * @param fund 基金实体
     */
    private void calculateFundPositionFromTransactions(PortfolioFundDto fundDto, Fund fund) {
        // 查询该基金的所有交易记录
        QueryWrapper<Transaction> transactionQuery = new QueryWrapper<>();
        transactionQuery.eq("fund_code", fund.getFundCode());
        transactionQuery.eq("status", "1");
        transactionQuery.orderByAsc("transaction_time");
        List<Transaction> transactions = transactionMapper.selectList(transactionQuery);
        
        // 计算总份额和总成本
        BigDecimal totalShares = BigDecimal.ZERO;
        BigDecimal totalCost = BigDecimal.ZERO;
        
        for (Transaction transaction : transactions) {
            if ("1".equals(transaction.getTransactionType())) {
                // 买入
                totalShares = totalShares.add(transaction.getShares());
                totalCost = totalCost.add(transaction.getAmount());
            } else if ("2".equals(transaction.getTransactionType())) {
                // 卖出
                totalShares = totalShares.subtract(transaction.getShares());
                // 按比例减少成本
                if (totalShares.compareTo(BigDecimal.ZERO) > 0) {
                    BigDecimal sellRatio = transaction.getShares().divide(totalShares.add(transaction.getShares()), 8, BigDecimal.ROUND_HALF_UP);
                    totalCost = totalCost.subtract(totalCost.multiply(sellRatio));
                } else {
                    totalCost = BigDecimal.ZERO;
                }
            }
        }
        
        fundDto.setShares(totalShares);
        
        if (fund.getNetValue() != null && totalShares.compareTo(BigDecimal.ZERO) > 0) {
            // 当前价值
            BigDecimal currentValue = fund.getNetValue().multiply(totalShares);
            fundDto.setNetValue(fund.getNetValue());
            fundDto.setCurrentValue(currentValue);
            
            // 成本和收益
            fundDto.setCost(totalCost);
            BigDecimal profit = currentValue.subtract(totalCost);
            fundDto.setProfit(profit);
            
            // 收益率
            if (totalCost.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal profitRate = profit.divide(totalCost, 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(BigDecimal.valueOf(100));
                fundDto.setProfitRate(profitRate);
            }
            
            // 买入价格（平均成本）
            if (totalShares.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal buyPrice = totalCost.divide(totalShares, 4, BigDecimal.ROUND_HALF_UP);
                fundDto.setBuyPrice(buyPrice);
            }
        }
    }

    @Override
    public int savePortfolio(PortfolioDto portfolioDto) {
        Portfolio portfolio = new Portfolio();
        BeanUtils.copyProperties(portfolioDto, portfolio);
        portfolio.setCreatedTime(sdf.format(new Date()));
        portfolio.setUpdatedTime(sdf.format(new Date()));
        if (portfolio.getStatus() == null || portfolio.getStatus().isEmpty()) {
            portfolio.setStatus("1"); // 1-有效 0-无效
        }
        return portfolioMapper.insert(portfolio);
    }

    @Override
    public void updatePortfolio(PortfolioDto portfolioDto) {
        Portfolio portfolio = new Portfolio();
        BeanUtils.copyProperties(portfolioDto, portfolio);
        portfolio.setUpdatedTime(sdf.format(new Date()));
        portfolioMapper.updateById(portfolio);
    }

    @Override
    public void deletePortfolio(Long id) {
        portfolioMapper.deleteById(id);
    }

    @Override
    public PortfolioDto getPortfolioById(Long id) {
        Portfolio portfolio = portfolioMapper.selectById(id);
        if (portfolio == null) {
            return null;
        }
        PortfolioDto portfolioDto = new PortfolioDto();
        BeanUtils.copyProperties(portfolio, portfolioDto);
        
        // 查询组合中的基金
        QueryWrapper<PortfolioFund> fundQueryWrapper = new QueryWrapper<>();
        fundQueryWrapper.eq("portfolio_id", id);
        fundQueryWrapper.eq("status", "1");
        List<PortfolioFund> portfolioFunds = portfolioFundMapper.selectList(fundQueryWrapper);
        
        // 转换为DTO并设置基金名称等信息
        List<PortfolioFundDto> fundDtos = portfolioFunds.stream().map(portfolioFund -> {
            PortfolioFundDto fundDto = new PortfolioFundDto();
            BeanUtils.copyProperties(portfolioFund, fundDto);
            
            // 获取基金详细信息
            QueryWrapper<Fund> fundQuery = new QueryWrapper<>();
            fundQuery.eq("fund_code", portfolioFund.getFundCode());
            fundQuery.eq("status", "1");
            Fund fund = fundMapper.selectOne(fundQuery);
            if (fund != null) {
                fundDto.setFundName(fund.getFundName());
                fundDto.setFundCode(fund.getFundCode());
                
                // 从交易记录中计算持仓信息
                calculateFundPositionFromTransactions(fundDto, fund);
            }
            
            return fundDto;
        }).collect(Collectors.toList());
        
        portfolioDto.setFunds(fundDtos);
        
        // 计算组合总价值、总成本和总收益
        BigDecimal totalValue = BigDecimal.ZERO;
        BigDecimal totalCost = BigDecimal.ZERO;
        BigDecimal totalProfit = BigDecimal.ZERO;
        
        for (PortfolioFundDto fundDto : fundDtos) {
            if (fundDto.getCurrentValue() != null) {
                totalValue = totalValue.add(fundDto.getCurrentValue());
            }
            if (fundDto.getCost() != null) {
                totalCost = totalCost.add(fundDto.getCost());
            }
            if (fundDto.getProfit() != null) {
                totalProfit = totalProfit.add(fundDto.getProfit());
            }
        }
        
        portfolioDto.setTotalValue(totalValue);
        portfolioDto.setTotalCost(totalCost);
        portfolioDto.setTotalProfit(totalProfit);
        
        if (totalCost.compareTo(BigDecimal.ZERO) != 0) {
            BigDecimal totalProfitRate = totalProfit.divide(totalCost, 4, BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100));
            portfolioDto.setTotalProfitRate(totalProfitRate);
        }
        
        return portfolioDto;
    }

    @Override
    public Page<PortfolioDto> getPortfoliosByConditions(String portfolioName, int pageNo, int pageSize) {
        Page<Portfolio> page = new Page<>(pageNo, pageSize);
        QueryWrapper<Portfolio> queryWrapper = new QueryWrapper<>();
        if (portfolioName != null && !portfolioName.isEmpty()) {
            queryWrapper.like("portfolio_name", portfolioName);
        }
        queryWrapper.eq("status", "1");
        portfolioMapper.selectPage(page, queryWrapper);

        Page<PortfolioDto> dtoPage = new Page<>(pageNo, pageSize, page.getTotal());
        List<PortfolioDto> records = page.getRecords().stream().map(portfolio -> {
            PortfolioDto dto = new PortfolioDto();
            BeanUtils.copyProperties(portfolio, dto);
            
            // 查询组合中的基金
            QueryWrapper<PortfolioFund> fundQueryWrapper = new QueryWrapper<>();
            fundQueryWrapper.eq("portfolio_id", portfolio.getId());
            fundQueryWrapper.eq("status", "1");
            List<PortfolioFund> portfolioFunds = portfolioFundMapper.selectList(fundQueryWrapper);
            
            // 计算组合总价值、总成本和总收益
            BigDecimal totalValue = BigDecimal.ZERO;
            BigDecimal totalCost = BigDecimal.ZERO;
            BigDecimal totalProfit = BigDecimal.ZERO;
            
            for (PortfolioFund portfolioFund : portfolioFunds) {
                // 获取基金详细信息
                QueryWrapper<Fund> fundQuery = new QueryWrapper<>();
                fundQuery.eq("fund_code", portfolioFund.getFundCode());
                fundQuery.eq("status", "1");
                Fund fund = fundMapper.selectOne(fundQuery);
                
                if (fund != null) {
                    // 从交易记录中计算持仓信息
                    PortfolioFundDto fundDto = new PortfolioFundDto();
                    BeanUtils.copyProperties(portfolioFund, fundDto);
                    calculateFundPositionFromTransactions(fundDto, fund);
                    
                    if (fundDto.getCurrentValue() != null) {
                        totalValue = totalValue.add(fundDto.getCurrentValue());
                    }
                    if (fundDto.getCost() != null) {
                        totalCost = totalCost.add(fundDto.getCost());
                    }
                    if (fundDto.getProfit() != null) {
                        totalProfit = totalProfit.add(fundDto.getProfit());
                    }
                }
            }
            
            dto.setTotalValue(totalValue);
            dto.setTotalCost(totalCost);
            dto.setTotalProfit(totalProfit);
            
            if (totalCost.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal totalProfitRate = totalProfit.divide(totalCost, 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(BigDecimal.valueOf(100));
                dto.setTotalProfitRate(totalProfitRate);
            }
            
            return dto;
        }).collect(Collectors.toList());
        dtoPage.setRecords(records);
        return dtoPage;
    }

    @Override
    public List<PortfolioDto> getAllPortfolios() {
        QueryWrapper<Portfolio> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "1");
        List<Portfolio> portfolios = portfolioMapper.selectList(queryWrapper);
        return portfolios.stream().map(portfolio -> {
            PortfolioDto dto = new PortfolioDto();
            BeanUtils.copyProperties(portfolio, dto);
            
            // 查询组合中的基金
            QueryWrapper<PortfolioFund> fundQueryWrapper = new QueryWrapper<>();
            fundQueryWrapper.eq("portfolio_id", portfolio.getId());
            fundQueryWrapper.eq("status", "1");
            List<PortfolioFund> portfolioFunds = portfolioFundMapper.selectList(fundQueryWrapper);
            
            // 计算组合总价值、总成本和总收益
            BigDecimal totalValue = BigDecimal.ZERO;
            BigDecimal totalCost = BigDecimal.ZERO;
            BigDecimal totalProfit = BigDecimal.ZERO;
            
            for (PortfolioFund portfolioFund : portfolioFunds) {
                // 获取基金详细信息
                QueryWrapper<Fund> fundQuery = new QueryWrapper<>();
                fundQuery.eq("fund_code", portfolioFund.getFundCode());
                fundQuery.eq("status", "1");
                Fund fund = fundMapper.selectOne(fundQuery);
                
                if (fund != null) {
                    // 从交易记录中计算持仓信息
                    PortfolioFundDto fundDto = new PortfolioFundDto();
                    BeanUtils.copyProperties(portfolioFund, fundDto);
                    calculateFundPositionFromTransactions(fundDto, fund);
                    
                    if (fundDto.getCurrentValue() != null) {
                        totalValue = totalValue.add(fundDto.getCurrentValue());
                    }
                    if (fundDto.getCost() != null) {
                        totalCost = totalCost.add(fundDto.getCost());
                    }
                    if (fundDto.getProfit() != null) {
                        totalProfit = totalProfit.add(fundDto.getProfit());
                    }
                }
            }
            
            dto.setTotalValue(totalValue);
            dto.setTotalCost(totalCost);
            dto.setTotalProfit(totalProfit);
            
            if (totalCost.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal totalProfitRate = totalProfit.divide(totalCost, 4, BigDecimal.ROUND_HALF_UP)
                        .multiply(BigDecimal.valueOf(100));
                dto.setTotalProfitRate(totalProfitRate);
            }
            
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public void addFundToPortfolio(Long portfolioId, String fundCode, String shares, String buyPrice, String buyTime) {
        // 首先检查是否已经添加过该基金
        QueryWrapper<PortfolioFund> checkWrapper = new QueryWrapper<>();
        checkWrapper.eq("portfolio_id", portfolioId);
        checkWrapper.eq("fund_code", fundCode);
        checkWrapper.eq("status", "1");
        PortfolioFund existingFund = portfolioFundMapper.selectOne(checkWrapper);
        
        if (existingFund != null) {
            // 如果已存在，不需要重复添加
            return;
        }
        
        PortfolioFund portfolioFund = new PortfolioFund();
        portfolioFund.setPortfolioId(portfolioId);
        portfolioFund.setFundCode(fundCode);
        portfolioFund.setCreatedTime(sdf.format(new Date()));
        portfolioFund.setUpdatedTime(sdf.format(new Date()));
        portfolioFund.setStatus("1");
        
        // shares, buyPrice, buyTime 字段不再使用，设为默认值
        portfolioFund.setShares(BigDecimal.ZERO);
        portfolioFund.setBuyPrice(BigDecimal.ZERO);
        portfolioFund.setBuyTime("");
        
        portfolioFundMapper.insert(portfolioFund);
    }

    @Override
    public void removeFundFromPortfolio(Long portfolioId, Long fundId) {
        QueryWrapper<PortfolioFund> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("portfolio_id", portfolioId);
        queryWrapper.eq("id", fundId);
        portfolioFundMapper.delete(queryWrapper);
    }
}